package com.carrental.finance.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.carrental.finance.dto.InvoiceDTO;
import com.carrental.finance.entity.Invoice;
import com.carrental.finance.mapper.InvoiceMapper;
import com.carrental.finance.service.InvoiceService;
import com.carrental.finance.vo.InvoiceVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 发票服务实现类
 */
@Service
public class InvoiceServiceImpl extends ServiceImpl<InvoiceMapper, Invoice> implements InvoiceService {

    /**
     * 创建发票
     *
     * @param invoiceDTO 发票DTO
     * @return 发票ID
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createInvoice(InvoiceDTO invoiceDTO) {
        // 生成发票号
        String invoiceNo = generateInvoiceNo();
        
        Invoice invoice = new Invoice();
        BeanUtils.copyProperties(invoiceDTO, invoice);
        invoice.setInvoiceNo(invoiceNo);
        invoice.setStatus(1); // 默认状态为待开具
        invoice.setCreateTime(LocalDateTime.now());
        invoice.setUpdateTime(LocalDateTime.now());
        
        // 保存发票记录
        save(invoice);
        
        return invoice.getId();
    }

    /**
     * 根据ID获取发票详情
     *
     * @param id 发票ID
     * @return 发票VO
     */
    @Override
    public InvoiceVO getInvoiceById(Long id) {
        Invoice invoice = getById(id);
        if (invoice == null) {
            return null;
        }
        
        return convertToVO(invoice);
    }

    /**
     * 根据发票号获取发票详情
     *
     * @param invoiceNo 发票号
     * @return 发票VO
     */
    @Override
    public InvoiceVO getInvoiceByInvoiceNo(String invoiceNo) {
        LambdaQueryWrapper<Invoice> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Invoice::getInvoiceNo, invoiceNo);
        
        Invoice invoice = getOne(wrapper);
        if (invoice == null) {
            return null;
        }
        
        return convertToVO(invoice);
    }

    /**
     * 根据订单ID获取发票详情
     *
     * @param orderId 订单ID
     * @return 发票VO
     */
    @Override
    public InvoiceVO getInvoiceByOrderId(Long orderId) {
        LambdaQueryWrapper<Invoice> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Invoice::getOrderId, orderId);
        
        Invoice invoice = getOne(wrapper);
        if (invoice == null) {
            return null;
        }
        
        return convertToVO(invoice);
    }

    /**
     * 根据用户ID分页查询发票
     *
     * @param userId 用户ID
     * @param page   分页参数
     * @return 发票VO分页
     */
    @Override
    public Page<InvoiceVO> pageUserInvoices(Long userId, Page<Invoice> page) {
        LambdaQueryWrapper<Invoice> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Invoice::getUserId, userId);
        wrapper.orderByDesc(Invoice::getCreateTime);
        
        Page<Invoice> invoicePage = page(page, wrapper);
        
        return convertToVOPage(invoicePage);
    }

    /**
     * 分页查询发票
     *
     * @param page        分页参数
     * @param invoiceNo   发票号
     * @param orderNo     订单号
     * @param userId      用户ID
     * @param invoiceType 发票类型
     * @param status      发票状态
     * @param startTime   开始时间
     * @param endTime     结束时间
     * @return 发票VO分页
     */
    @Override
    public Page<InvoiceVO> pageInvoices(Page<Invoice> page, String invoiceNo, String orderNo, Long userId, Integer invoiceType, Integer status, String startTime, String endTime) {
        LambdaQueryWrapper<Invoice> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.isNotBlank(invoiceNo), Invoice::getInvoiceNo, invoiceNo);
        wrapper.like(StringUtils.isNotBlank(orderNo), Invoice::getOrderNo, orderNo);
        wrapper.eq(userId != null, Invoice::getUserId, userId);
        wrapper.eq(invoiceType != null, Invoice::getInvoiceType, invoiceType);
        wrapper.eq(status != null, Invoice::getStatus, status);
        
        if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            LocalDateTime start = LocalDateTime.parse(startTime, formatter);
            LocalDateTime end = LocalDateTime.parse(endTime, formatter);
            wrapper.between(Invoice::getCreateTime, start, end);
        }
        
        wrapper.orderByDesc(Invoice::getCreateTime);
        
        Page<Invoice> invoicePage = page(page, wrapper);
        
        return convertToVOPage(invoicePage);
    }

    /**
     * 开具发票
     *
     * @param id 发票ID
     * @return 是否成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean issueInvoice(Long id) {
        Invoice invoice = getById(id);
        if (invoice == null) {
            return false;
        }
        
        // 只有待开具的发票可以开具
        if (invoice.getStatus() != 1) {
            return false;
        }
        
        // 更新发票状态为已开具
        invoice.setStatus(2);
        invoice.setInvoiceTime(LocalDateTime.now());
        invoice.setUpdateTime(LocalDateTime.now());
        
        return updateById(invoice);
    }

    /**
     * 作废发票
     *
     * @param id 发票ID
     * @return 是否成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean invalidateInvoice(Long id) {
        Invoice invoice = getById(id);
        if (invoice == null) {
            return false;
        }
        
        // 只有已开具的发票可以作废
        if (invoice.getStatus() != 2) {
            return false;
        }
        
        // 更新发票状态为已作废
        invoice.setStatus(3);
        invoice.setUpdateTime(LocalDateTime.now());
        
        return updateById(invoice);
    }

    /**
     * 更新发票电子URL
     *
     * @param id         发票ID
     * @param invoiceUrl 电子发票URL
     * @return 是否成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateInvoiceUrl(Long id, String invoiceUrl) {
        Invoice invoice = getById(id);
        if (invoice == null) {
            return false;
        }
        
        // 更新电子发票URL
        invoice.setInvoiceUrl(invoiceUrl);
        invoice.setUpdateTime(LocalDateTime.now());
        
        return updateById(invoice);
    }

    /**
     * 生成发票号
     */
    private String generateInvoiceNo() {
        // 生成格式为：I + 当前时间（年月日时分秒）+ 6位随机数
        String timeStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        String randomStr = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 6);
        return "I" + timeStr + randomStr;
    }

    /**
     * 转换发票实体为VO
     */
    private InvoiceVO convertToVO(Invoice invoice) {
        if (invoice == null) {
            return null;
        }
        
        InvoiceVO vo = new InvoiceVO();
        BeanUtils.copyProperties(invoice, vo);
        
        // 设置发票类型名称
        vo.setInvoiceTypeName(getInvoiceTypeName(invoice.getInvoiceType()));
        
        // 设置发票状态名称
        vo.setStatusName(getStatusName(invoice.getStatus()));
        
        // TODO: 调用用户服务获取用户信息
        
        return vo;
    }

    /**
     * 转换发票分页为VO分页
     */
    private Page<InvoiceVO> convertToVOPage(Page<Invoice> page) {
        Page<InvoiceVO> voPage = new Page<>();
        voPage.setCurrent(page.getCurrent());
        voPage.setSize(page.getSize());
        voPage.setTotal(page.getTotal());
        
        List<InvoiceVO> voList = page.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
        
        voPage.setRecords(voList);
        return voPage;
    }

    /**
     * 获取发票类型名称
     */
    private String getInvoiceTypeName(Integer invoiceType) {
        if (invoiceType == null) {
            return "";
        }
        
        switch (invoiceType) {
            case 1:
                return "普通发票";
            case 2:
                return "增值税专用发票";
            default:
                return "未知类型";
        }
    }

    /**
     * 获取发票状态名称
     */
    private String getStatusName(Integer status) {
        if (status == null) {
            return "";
        }
        
        switch (status) {
            case 1:
                return "待开具";
            case 2:
                return "已开具";
            case 3:
                return "已作废";
            default:
                return "未知状态";
        }
    }
} 